package com.yonyou.crm.common.model.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;
import org.apache.commons.beanutils.converters.SqlDateConverter;
import org.apache.commons.beanutils.converters.SqlTimeConverter;
import org.apache.commons.beanutils.converters.SqlTimestampConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yonyou.crm.common.page.entity.Page;

public class ModelUtil {

	private final static Logger logger = LoggerFactory.getLogger(ModelUtil.class);
	
	static {  
		ConvertUtils.register(new SqlDateConverter(null), java.util.Date.class);
    }  
	
	/**
	 * 复制分页实体
	 * @param origPage 来源分页对象
	 * @param destClass 目标类型
	 * @return
	 */
	public static <O, D> Page<D> copyPageModel(Page<O> origPage, Class<D> destClass){
		return copyPageModel(origPage, destClass, null);
	}
	
	/**
	 * 复制分页实体
	 * @param origPage 来源分页对象
	 * @param destClass 目标类型
	 * @param converter 转换器
	 * @return
	 */
	public static <O, D> Page<D> copyPageModel(Page<O> origPage, Class<D> destClass, IConverter<O, D> converter){
		
		Page<D> destPage = new Page<D>();
		try {
			BeanUtils.copyProperties(destPage, origPage);
			destPage.setData(copyModelList(origPage.getData(), destClass, converter));
		} catch (Exception e) {
		}
		
		return destPage;
	}
	
	/**
	 * 复制实体列表
	 * @param origObjList 来源对象列表
	 * @param destClass 目标类型
	 * @return
	 */
	public static <O, D> List<D> copyModelList(List<O> origObjList, Class<D> destClass){
		return copyModelList(origObjList, destClass, null);
	}
	
	/**
	 * 复制实体列表
	 * @param origObjList 来源对象列表
	 * @param destClass 目标类
	 * @param converter 转换器
	 * @return
	 */
	public static <O, D> List<D> copyModelList(List<O> origObjList, Class<D> destClass, IConverter<O, D> converter){
		
		if (origObjList == null) {
			return null;
		}

		List<D> destObjList = new ArrayList<D>();
		for (O origObj : origObjList) {
			destObjList.add(copyModel(origObj, destClass, converter));
		}
		return destObjList;
	}
	
	/**
	 * 复制实体
	 * @param origObj 来源对象
	 * @param destClass 目标类型
	 * @return
	 */
	public static <O, D> D copyModel(O origObj, Class<D> destClass){
		return copyModel(origObj, destClass, null);
	}
	
	/**
	 * 复制实体
	 * @param origObj 来源对象
	 * @param destClass 目标类型
	 * @param converter 转换器
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <O, D> D copyModel(O origObj, Class<D> destClass, IConverter<O, D> converter){
		
		if (origObj == null || destClass == null) {
			return null;
		}
		
		D destObj = null;
		
		try {
			destObj = (D) Class.forName(destClass.getName()).newInstance();
			//BeanUtils.copyProperties(destObj, origObj);
			BeanUtilsBean beanUtilsBean = new BeanUtilsBean(); 
			//BigDecimal、Date等类型的字段值为null时转换会抛异常，需要以下Converter进行处理 
		    ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class); 
		    beanUtilsBean.getConvertUtils().register(new LongConverter(null), Long.class);
		    beanUtilsBean.getConvertUtils().register(new ShortConverter(null), Short.class);
		    beanUtilsBean.getConvertUtils().register(new IntegerConverter(null), Integer.class);
		    beanUtilsBean.getConvertUtils().register(new DoubleConverter(null), Double.class);
			beanUtilsBean.getConvertUtils().register(new BigDecimalConverter(null), BigDecimal.class);
			beanUtilsBean.getConvertUtils().register(new DateConverter(null), java.util.Date.class);
			beanUtilsBean.getConvertUtils().register(new SqlTimestampConverter(null), java.sql.Timestamp.class);  
			beanUtilsBean.getConvertUtils().register(new SqlDateConverter(null), java.sql.Date.class);  
			beanUtilsBean.getConvertUtils().register(new SqlTimeConverter(null), java.sql.Time.class);
			beanUtilsBean.copyProperties(destObj, origObj);
			if (converter != null) {
				converter.convert(origObj, destObj);
			}
		} catch (Exception e) {
		}
		return destObj;
	}
}
